package com.bobo.base.network.base;


import android.os.Build;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.RequiresApi;

import com.bobo.base.network.util.KLog;
import com.bobo.base.utils.sign.DESDemo;
import com.bobo.base.utils.sign.Sha256;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;

public class UrlInterceptor implements Interceptor {
    private LinkedList<String> urlList = new LinkedList<>();

    public UrlInterceptor() {
        // 需要过滤的接口添加在此处
        urlList.add("api/sns/bbs/article/unLike");
        urlList.add("/dev-api/api/sns/bbs/article/unLike");// 测试环境路径
        urlList.add("/api/customer/pushScrollReward");
        urlList.add("/api/customer/pushScroll");
        urlList.add("/api/login/registerUser");
        urlList.add("/api/login/login");
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        HttpUrl urls = request.url();
//        if(!urlList.contains(urls.encodedPath())){
//            return chain.proceed(request);
//        }
        //作用：将post中的请求参数取出加密，并且替换原来的请求参数；ps：重新添加的参数是Query形式，并未添加到encode中
        //将加密后的data直接使用addEnable请求不成功，可能和后台的请求类型有关系
        SortedMap<String, Object> map = new TreeMap<>();
        String time = String.valueOf(System.currentTimeMillis());
        try {
//            if ("GET".equals(request.method()) && request.url().encodedQuery() != null) {//获取get请求的参数
//            String encodedQuery = request.url().encodedQuery();
//            String[] querys = encodedQuery.split("&");
//            Map<String, String> queryMap = new HashMap<>();
//            for (String query : querys) {
//                String[] split = query.split("=");
//                queryMap.put(split[0], split[1]);
//            }
//            //获取get请求参数后可进行排序
//            List<Map.Entry<String, String>> entryList = new ArrayList<>(queryMap.entrySet());
//            Collections.sort(entryList, new Comparator<Map.Entry<String, String>>() {
//                @Override
//                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
//                    return o1.getKey().compareTo(o2.getKey());
//                }
//            });
//            /*省略签名计算*/
//        } else
            if ("POST".equals(request.method()) || "PUT".equals(request.method())) {//post请求有参数时
                if (request.body() instanceof FormBody) {//post请求有参数时
                    FormBody formBody = (FormBody) request.body();
                    if (formBody.size() > 0) {
                        for (int i = 0; i < formBody.size(); i++) {//将post请求的参数依次取出再加密
                            map.put(formBody.encodedName(i), formBody.encodedValue(i));
                        }
                    }

                    Map<String, Object> resultMap = sortMapByKey(map);//按Key进行排序
                    JSONObject jsonObject = new JSONObject(resultMap);

//                    String sign = Sha256.getSHA256(DESDemo.desEncript(Base64.getEncoder().encodeToString((jsonObject.toString() + time).getBytes()),DESDemo.originKey));
                    String str = DESDemo.originKey + jsonObject.toString() + time;
                    String sign = Sha256.getSHA256(str);
//                    KLog.e("原来的：" + str);
//                    KLog.e("DES加密：" + DESDemo.desEncript(Base64.getEncoder().encodeToString((jsonObject.toString() + time).getBytes()),DESDemo.originKey));
//                    KLog.e("加密的：" + sign);
//                    KLog.e("解密：" + DESDemo.desDecript(sign, DESDemo.originKey));
//                    KLog.e("解密1：" + Base64.getDecoder().decode(DESDemo.desDecript(sign, DESDemo.originKey)));

                    request = request.newBuilder()
                            .addHeader("sign", sign)
                            .addHeader("timestamp", time)
                            .build();
//                request = request.newBuilder()
//                        .post(bodyBuilder.build())//请求新的请求参数
//                        .url(request.url()
//                                .newBuilder()
//                                .addQueryParameter("param", AESUtil.encryptCbcMode(map))  //data是需要的字段
//                                .build())
//                        .build();
                }else if (request.body() instanceof MultipartBody) {
//                    String url = request.url().toString();//获取完整的url
//                String[] parts = url.split("\\?");//将url中的地址和参数分开
//                if (parts.length > 1) {//后面的参数
//                    String[] params = parts[1].split("&");
//                    for (String pair : params) {
//                        String[] param = pair.split("=");
//                        if (param.length != 2) {
//                            //没有value的参数不进行处理
//                            continue;
//                        }
//                        map.put(param[0], param[1]);
//                    }
//
//                }
//                //添加的part的位置不能错乱
//                MultipartBody.Builder multiBuilder = new MultipartBody.Builder();
//                //将加密后的参数放在part上
//                multiBuilder.addPart(
//                        Headers.of("Content-Disposition", "form-data; name=\"data\"", "Content-Transfer-Encoding", "binary"),
//                        RequestBody.create(MediaType.parse("text/plain; charset=UTF-8"), AESUtil.encryptCbcMode(map)));
//
//                MultipartBody multipartBody = (MultipartBody) request.body();
//                if (multipartBody.parts().size() > 0) {//原来文件中需要上传的图片；不需要加密
//                    for (MultipartBody.Part part : multipartBody.parts()) {
//                        if (!"image/jpg".equals(part.body().contentType().toString())) {//图片类型 上传
//                            continue;
//                        }
//                        multiBuilder.addPart(part);
//                    }
//
//                }
//                request = new Request.Builder()//新建一个request
//                        .post(multiBuilder.build())//将新的MultipartBody添加进去
//                        .build();
//
////                            request = new Request.Builder()
////                                    .url(parts[0])
////                                    .post(multiBuilder
////                                            .build())
////                                    .build();//将后面的参数截取掉
////                            request = request.newBuilder()
////                                    .url(request.url()
////                                            .newBuilder()
////                                            .addQueryParameter("data", RSAUtils.encrypt(map))
////                                            .build())
////                                    .build();
                    return chain.proceed(request);
                } else {
                    //        参数处理
                    String json = parseParams(request);
                    if(TextUtils.isEmpty(json))
                        return chain.proceed(request);

                    Map<String, Object> infoMap = jsonToMap(json);
                    if(infoMap == null)
                        return chain.proceed(request);

                    for (String key : infoMap.keySet()) {
                        map.put(key, infoMap.get(key));
                    }

                    Map<String, Object> resultMap = sortMapByKey(map);//按Key进行排序
                    JSONObject jsonObject = new JSONObject(resultMap);

//                    String str = jsonObject.toString() + time;
//                    String sign = Sha256.getSHA256(DESDemo.desEncript(Base64.getEncoder().encodeToString((jsonObject.toString() + time).getBytes()),DESDemo.originKey));
                    String str = DESDemo.originKey + jsonObject.toString() + time;
                    String sign = Sha256.getSHA256(str);
                    KLog.e("原来的：" + str);
//                    KLog.e("DES加密：" + DESDemo.desEncript(Base64.getEncoder().encodeToString((jsonObject.toString() + time).getBytes()),DESDemo.originKey));
                    KLog.e("加密的：" + sign);
//                    KLog.e("解密：" + DESDemo.desDecript(sign, DESDemo.originKey));
//                    KLog.e("解密1：" + new String(Base64.getDecoder().decode(DESDemo.desDecript(sign, DESDemo.originKey))));

                    request = request.newBuilder()
                            .addHeader("sign", sign)
                            .addHeader("timestamp", time)
                            .build();
                }

            }
//            }else{
//                HttpUrl url = request.url();
//                /*本次请求的接口地址*/
//                String apiPath = url.scheme()+ "://" + url.host()+ ":" +url.port() + url.encodedPath();
//                /*服务端的接口地址*/
//                String serverPath = "${url.scheme()}://${url.host()}/".trim();
//                if (url.encodedQuery() != null) {
//                    try {
//                        String queryparamNames = request.url().encodedQuery();
//                        String[] params = queryparamNames.split("&");
//                        for (String pair : params) {
//                            String[] param = pair.split("=");
//                            if (param.length != 2) {
//                                //没有value的参数不进行处理
//                                continue;
//                            }
//                            map.put(param[0], param[1]);
//                        }
//                        //拼接加密后的url，参数字段自己跟后台商量，这里我用param，后台拿到数据先对param进行解密，解密后的数据就是请求的数据
//                        String newUrl = apiPath + "?param="+ AESUtil.encryptCbcMode(map);
//                        //构建新的请求
//                        request = request.newBuilder().url(newUrl ).build();
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                        return chain.proceed(request);
//                    }
//                }
//            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return chain.proceed(request);
    }



//    private String signFn(Request request) {
//        String signStr;
//        String type = request.method();
//
//        if (type.equals("GET") && request.url().encodedQuery() != null) {//获取get请求的参数
//            String encodedQuery = request.url().encodedQuery();
//            String[] querys = encodedQuery.split("&");
//            Map<String, String> queryMap = new HashMap<>();
//            for (String query : querys) {
//                String[] split = query.split("=");
//                queryMap.put(split[0], split[1]);
//            }
//            //获取get请求参数后可进行排序
//            List<Map.Entry<String, String>> entryList = new ArrayList<>(queryMap.entrySet());
//            Collections.sort(entryList, new Comparator<Map.Entry<String, String>>() {
//                @Override
//                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
//                    return o1.getKey().compareTo(o2.getKey());
//                }
//            });
//            /*省略签名计算*/
//        } else if (type.equals("POST")) {//获取POST请求的参数
//            String paramsStr = bodyToString(request);
//            /*省略签名计算*/
//        }
//        return signStr;
//    }

    /**
     * 将json转成Map
     *  会将属性中的long转换成String
     * @param json
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
    private Map<String, Object> jsonToMap1(String json) {
        Map<String, Object> map = new HashMap<>();
        JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
        jsonObject.keySet().forEach(keyStr ->{
            Object keyvalue = jsonObject.get(keyStr);
            map.put(keyStr, keyvalue);
        });
        System.out.println(map);
        return map;



        // 先转成 JSONObject 对象
//        Map<String, Object> infoMap = null;
//        try {
//            JSONObject jObject = new JSONObject(json);
//            // 设置 Long数值型的转换策略
//            Gson gsonBuilder = new GsonBuilder()
//                    .setLongSerializationPolicy(LongSerializationPolicy.DEFAULT)
//                    .create();
//            String jsonBu = gsonBuilder.toJson(jObject);
//
//            infoMap = gsonBuilder.fromJson(jsonBu, new TypeToken<Map<String, Object>>() {}.getType());
//        } catch (JSONException e) {
//            e.printStackTrace();
//        }
//        return infoMap;
    }

    /**
     * json 转map
     * 防止将long类型转成String
     * @param content
     * @return
     */
    private Map<String, Object> jsonToMap(String content) {
        content = content.trim();
        Map<String, Object> result = new HashMap<>();
        try {
            if (content.charAt(0) == '[') {
                JSONArray jsonArray = new JSONArray(content);
                for (int i = 0; i < jsonArray.length(); i++) {
                    Object value = jsonArray.get(i);
                    if (value instanceof JSONArray || value instanceof JSONObject) {
                        result.put(i + "", jsonToMap(value.toString().trim()));
                    } else {
                        result.put(i + "", jsonArray.getString(i));
                    }
                }
            } else if (content.charAt(0) == '{'){
                JSONObject jsonObject = new JSONObject(content);
                Iterator<String> iterator = jsonObject.keys();
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    Object value = jsonObject.get(key);
                    if(value == null || TextUtils.equals("null", value.toString()))
                        continue;
//                    if (value instanceof JSONArray || value instanceof JSONObject) {
//                        result.put(key, jsonToMap(value.toString().trim()));
                    if (value instanceof JSONArray) {
                        result.put(key, new JSONArray());
                    } else if (value instanceof JSONObject) {
                        result.put(key, new JSONObject());
                    } else {
                        result.put(key, value);
                    }
                }
            }else {
                Log.e("异常", "json2Map: 字符串格式错误");
            }
        } catch (JSONException e) {
            Log.e("异常", "json2Map: ", e);
            result = null;
        }
        return result;
    }

    private static String bodyToString(final RequestBody request) {
        try {
            final RequestBody copy = request;
            final Buffer buffer = new Buffer();
            if (copy != null)
                copy.writeTo(buffer);
            else
                return "";
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "did not work";
        }
    }

    private String parseParams(Request request) {
        try {
            RequestBody body = request.body();
            if(body == null)
                return "";
            Buffer requestbuffer = new Buffer();
            body.writeTo(requestbuffer);
            Charset charset = Charset.forName("UTF-8");
            MediaType contentType = body.contentType();
            if (contentType != null) {
                charset = contentType.charset(charset);
            }
            String json = requestbuffer.readString(charset);
//            if (hasUrlEncoded(json)) {
//                json = URLDecoder.decode(
//                        json,
//                        convertCharset(charset)
//                );
//            }
//            return jsonFormat(json);
            return json;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    private String convertCharset(Charset charset) {
        String s = charset.toString();
        int i = s.indexOf("[");
        return i == -1 ? s : s.substring(i + 1, s.length() - 1);
    }

    /**
     * 使用 Map按key进行排序
     *
     * @param map
     * @return
     */
    public static TreeMap<String, Object> sortMapByKey(Map<String, Object> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }

        TreeMap<String, Object> sortMap = new TreeMap<String, Object>(new MapKeyComparator());

        sortMap.putAll(map);

        return sortMap;

    }

    static class MapKeyComparator implements Comparator<String> {

        @Override
        public int compare(String str1, String str2) {

            return str1.compareTo(str2);
        }
    }

}